package com.datang.litejvm.cmd;

import com.datang.litejvm.constant.ConstantClassInfo;
import com.datang.litejvm.constant.ConstantPool;
import com.datang.litejvm.engin.ExecutionResult;
import com.datang.litejvm.engin.Heap;
import com.datang.litejvm.engin.JavaObject;
import com.datang.litejvm.engin.StackFrame;

/**
 * @author: 顶风少年
 * @Description: 0xbb new 创建一个对象，并将其引用值压入栈顶。
 * @date: 19:09 2022/6/16
 **/
public class NewObjectCmd extends TwoOperandCmd {
    public NewObjectCmd(ConstantPool pool, String opCode) {
        super(pool, opCode);
    }

    @Override
    public String toString() {
        return super.toString();
    }

    /**
     * @author: 顶风少年
     * @Description: 创建一个对象
     * 无符号数 indexbyte1 和 indexbyte2 用于构建一个当前类（§2.6）的运
     * 行时常量池的索引值，构建方式为（indexbyte1 << 8）| indexbyte2，
     * 该索引所指向的运行时常量池项应当是一个类或接口的符号引用，这个类或接
     * 口类型应当是已被解析（§5.4.3.1）并且最终解析结果为某个具体的类型。
     * 一个以此为类型为对象将会被分配在 GC 堆中，并且它所有的实例变量都会进
     * 行初始化为相应类型的初始值（§2.3，§2.4）。一个代表该对象实例的
     * reference 类型数据 objectref 将压入到操作数栈中。
     * 对于一个已成功解析但是未初始化（§5.5）的类型，在这时将会进行初始化。
     * @date: 19:12 2022/6/16
     **/
    @Override
    public void execute(StackFrame frame, ExecutionResult result) {
        int index = this.getIndex();
        ConstantClassInfo info = (ConstantClassInfo) this.getConstantInfo(index);
        String clName = info.getClassName();
        JavaObject javaObject = Heap.getInstance().newObject(clName);
        //加入操作数栈
        frame.getOperandStack().push(javaObject);
    }

}
